const path = require('path')
const fs = require('fs-extra')
const sharp = require('sharp')
const { execSync, spawn } = require('child_process')
const iconv = require('iconv-lite') // 用于编码转换

//#region 
function wsfb(wss, callback) {
    wss.on('connection', ws => {
        // console.log(`【${wss.options.port}】新的WebSocket连接`)
        // console.log(`\x1B[42m ${wss.options.port} \x1B[0m 新的WebSocket连接`)

        const send = (header, data, code = 0) => ws.send(JSON.stringify({
            data: data,
            code: code,
            header: header
        }))

        const error = ({ data, code = 1, header }) => ws.send(JSON.stringify({
            msg: data,
            code: code,
            header: header
        }))

        // 监听消息事件
        ws.on('message', message => callback({
            msg: JSON.parse(message.toString()),
            send: send,
            error: error,
            ws: ws
        }))

        // 监听关闭事件
        ws.on('close', () => console.log(`\x1B[47m ${wss.options.port} \x1B[0m WebSocket连接关闭`))
    })
}
//#endregion


const wsf = {
    图形情感: wss => wsfb(wss, ({ msg, send, error, ws }) => {

        switch (msg.req) {
            case 'check':
                // 握手 & 轮询
                console.log(`\x1B[42m ${wss.options.port} \x1B[0m WebSocket连接成功`)

                send('check', 'ok')
                break;
            case 'close':
                send('check', 'bye', 1)
                break;
            case "getData":
                const getData = filename => {
                    return JSON.parse(fs.readFileSync(path.resolve(__dirname, `./src/${msg.path}/${filename}.json`)).toString())
                }

                // 分散数据分布减少单个文件的大小
                const bgc = getData('background')
                const struMain = getData('structure.main')
                const struSec = getData('structure.sec')

                // 
                const exportData = JSON.stringify({
                    structure: {
                        main: struMain,
                        secondary: struSec
                    },
                    background: bgc
                })

                send(exportData)
                break;
            case "get-img-info":
                const imagePath = path.resolve(__dirname, msg.path);
                
                // 检查文件是否存在
                if (!fs.existsSync(imagePath)) {
                    error({
                        data: `图片文件不存在: ${imagePath}`,
                        header: msg.req
                    });
                    break;
                }

                sharp(imagePath)
                    .metadata()
                    .then(metadata => {
                        send(msg.req, metadata)
                    })
                    .catch(err => {
                        error({
                            data: `图片处理失败: ${err.message}`,
                            header: msg.req
                        });
                    });

                break
            case "get-img-line": {

                const imagePath = path.resolve(__dirname, msg.path);
                
                // 检查文件是否存在
                if (!fs.existsSync(imagePath)) {
                    error({
                        data: `图片文件不存在: ${imagePath}`,
                        header: msg.req
                    });
                    break;
                }

                // 创建 sharp 处理管道
                sharp(imagePath)
                    .metadata()
                    .then(metadata => {
                        // 计算缩放尺寸（禁止放大）
                        const targetWidth = Math.max(1, Math.floor(metadata.width * msg.scaleRate));
                        const targetHeight = Math.max(1, Math.floor(metadata.height * msg.scaleRate));

                        // 配置高质量缩放
                        return sharp(imagePath)
                            .resize({
                                width: targetWidth,
                                height: targetHeight,
                                kernel: sharp.kernel.lanczos3, // 最佳质量缩小算法
                                fastShrinkOnLoad: false       // 禁用快速缩小（保证质量）
                            })
                            .raw()
                            .toBuffer({ resolveWithObject: true })
                            .then(({ data: buffer, info }) => ({
                                buffer,
                                width: info.width,
                                height: info.height,
                                channels: info.channels,
                                path: imagePath
                            }));
                    })
                    .then(({ buffer, width, height, channels, path }) => {
                        // 异步逐行处理器
                        let currentRow = 0;

                        const processRow = () => {
                            if (currentRow >= height) return;

                            // 构建单行数据
                            const row = [];
                            const rowStart = currentRow * width * channels;

                            for (let x = 0; x < width; x++) {
                                const pixelStart = rowStart + x * channels;
                                row.push(
                                    buffer[pixelStart].toString(16).padStart(2, '0') +
                                    buffer[pixelStart + 1].toString(16).padStart(2, '0') +
                                    buffer[pixelStart + 2].toString(16).padStart(2, '0')
                                );
                            }

                            // 发送 WS 消息
                            ws.send(JSON.stringify({
                                code: 0,
                                token: `${msg.req}_${msg.token}`,
                                header: msg.req,
                                data: {
                                    row: row,
                                    height: height,
                                    width: width,
                                    rowIndex: currentRow,
                                    path: path
                                }
                            }));

                            // 异步处理下一行（避免阻塞事件循环）
                            currentRow++;
                            setImmediate(processRow); // 比 nextTick 更友好的调度
                        };

                        // 启动处理流程
                        processRow();
                    })
                    .catch(err => {
                        ws.send(JSON.stringify({
                            code: 500,
                            token: msg.token,
                            header: msg.req,
                            message: `图片处理失败: ${err.message}`
                        }));
                    });
                break;
            }
            case 'select-file':
                const filename = getPythonFileSelection(path.resolve('./src/demo2/'))

                send(msg.req, filename)
                break

            case 'calc-stru':

                const process = spawn('ipconfig', [], {
                    shell: true
                })

                process.output = ''

                process.stdout.on('data', data => {
                    const decoded = iconv.decode(data, 'gbk')

                    process.output += decoded
                })

                process.on('close', code => {
                    send(msg.req, {
                        code,
                        data: process.output
                    })
                })

                // send(msg.req, msg.data)

                break



            case 'calc-split':
                const scriptPath = path.join(__dirname, './py/split.py')

                const conf = {
                    path: msg.path,
                    k: msg.k,
                    min_px: msg.min_px,
                    color_thresh: msg.color_thresh
                }

                const calc_process = spawn('python', [scriptPath, JSON.stringify(conf)], {
                    windowsHide: true,
                    encoding: 'utf-8',
                })

                let calc_ret = ''
                calc_process.stdout.on('data', data => {
                    calc_ret += data
                    // console.log('输出:', decoded)
                })

                calc_process.stderr.on('data', data => {
                    const decoded = iconv.decode(data, 'gbk')
                    console.error(decoded)
                })

                calc_process.on('close', code => {
                    console.log(`子进程退出，代码: ${code}`);

                    setTimeout(() => {
                        send(msg.req, {
                            code: code,
                            data: calc_ret
                        })
                    })
                })

                break
            default:
                send(123, 321)
                break
        }
    })
}

function getPythonFileSelection(initialDir = null) {
    try {
        const scriptPath = path.join(__dirname, './py/folder_dialog.py');

        // 构建命令参数
        const args = [];
        if (initialDir !== null) {
            args.push(`"${initialDir}"`);  // 引号包裹防止空格问题
        }

        // 执行命令
        const result = execSync(`python "${scriptPath}" ${args.join(' ')}`, {
            windowsHide: true,
            encoding: 'utf-8',
            env: {
                ...process.env,
                DISPLAY: process.env.DISPLAY || ':0'
            }
        }).trim();

        return result || null;
    } catch (error) {
        console.error('执行错误:', error.stderr || error.message);
        return null;
    }
}

// 
var getData = {
    req: 'getData',
    path: 'demo'
}

module.exports = { wsf, wsfb }